using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class PlayerControl : MonoBehaviour
{
    public GameObject player;
    private Text playerMText;
    private Text timeText; // 用于显示倒计时的Text组件
    private Text newText; // 用于显示玩家移动距离的NewText组件
    private bool canMove = false; // 控制玩家是否可以移动
    Animator animator;
    private float lastMouseX; // 上一帧的鼠标X位置
    private float swipeThreshold = 20f; // 滑动阈值
    private bool isMouseDown = false; // 鼠标是否按下
    private float mouseDownX; // 鼠标按下时的X位置
    private float mouseDowny; // 鼠标按下时的y位置
    public float forwardSpeed = 5f; // 玩家自动向前移动的速度
    private float originalTimeScale = 1f; // 存储原始时间缩放值
    
    // 金币收集器组件引用
    private CoinCollector coinCollector;

    // Start is called before the first frame update
    void Start()
    {
        // 获取Animator组件
        if (player != null)
        {
            animator = player.GetComponent<Animator>();
        }
        
        // 如果从player对象上获取失败，再尝试从当前对象获取
        if (animator == null)
        {
            animator = GetComponent<Animator>();
        }
        
        // 如果player没有在Inspector中赋值，则默认使用自身
        if (player == null)
        {
            player = gameObject;
        }
        
        // 确保玩家对象有正确的标签
        if (player.tag != "Player")
        {
            player.tag = "Player";
        }
        
        // 确保玩家对象有碰撞器组件 - 强制使用BoxCollider以确保碰撞检测可靠性
        BoxCollider boxCollider = player.GetComponent<BoxCollider>();
        if (boxCollider == null)
        {
            // 添加BoxCollider组件
            boxCollider = player.AddComponent<BoxCollider>();
        }
        
        // 确保碰撞器配置正确
        boxCollider.size = new Vector3(1.2f, 2.2f, 1.2f); // 稍微增大碰撞器以提高检测灵敏度
        boxCollider.center = new Vector3(0, 1.1f, 0);
        boxCollider.isTrigger = false; // 确保不是触发器
        
        // 确保玩家对象有Rigidbody组件，这对于碰撞检测是必要的
        Rigidbody rb = player.GetComponent<Rigidbody>();
        if (rb == null)
        {
            rb = player.AddComponent<Rigidbody>();
        }
        
        // 确保刚体配置正确
        rb.isKinematic = false; // 设置为非运动学刚体，这样才能与其他碰撞器触发碰撞事件
        // 锁定旋转，避免物理引擎导致玩家旋转
        rb.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
        rb.drag = 0f; // 设置阻力为0，使移动更加流畅
        rb.angularDrag = 0.05f;
        
        // 初始化金币收集器组件
        InitializeCoinCollector();
        
        // 初始化上一帧鼠标位置
        lastMouseX = Input.mousePosition.x;
        
        // 查找UI组件
        FindPlayerMText();
        FindTimeText();
        FindNewText();
        
        // 存储原始时间缩放值并暂停游戏时间
        originalTimeScale = Time.timeScale;
        Time.timeScale = 0f;
        
        // 开始三秒倒计时
        StartCoroutine(CountdownTimer());
    }
    
    /// <summary>
    /// 初始化金币收集器组件
    /// </summary>
    private void InitializeCoinCollector()
    {
        // 尝试从player对象上获取CoinCollector组件
        coinCollector = player.GetComponent<CoinCollector>();
        
        // 如果没有找到，则添加CoinCollector组件
        if (coinCollector == null)
        {
            coinCollector = player.AddComponent<CoinCollector>();
        }
    }

    // 查找Panel下的PlayerM Text组件
    private void FindPlayerMText()
    {
        // 尝试通过名称查找Panel对象
        GameObject panel = GameObject.Find("Panel");
        if (panel != null)
        {
            // 直接按名称查找PlayerM组件
            GameObject playerMObj = panel.transform.Find("PlayerM")?.gameObject;
            
            if (playerMObj != null)
            {
                playerMText = playerMObj.GetComponent<Text>();
                if (playerMText != null)
                {
                    // 初始化PlayerM Text显示
                    playerMText.text = "0.00";
                    return;
                }
            }
            
            // 如果通过transform.Find未找到，尝试通过GetComponentsInChildren遍历查找
            Text[] texts = panel.GetComponentsInChildren<Text>(true);
            foreach (Text text in texts)
            {
                if (text.gameObject.name == "PlayerM")
                {
                    playerMText = text;
                    // 初始化PlayerM Text显示
                    playerMText.text = "0.00";
                    return;
                }
            }
        }
        
        // 如果Panel下未找到，尝试直接查找场景中名为PlayerM的GameObject
        GameObject scenePlayerMObj = GameObject.Find("PlayerM");
        if (scenePlayerMObj != null)
        {
            playerMText = scenePlayerMObj.GetComponent<Text>();
            if (playerMText != null)
            {
                // 初始化PlayerM Text显示
                playerMText.text = "0.00";
            }
        }
    }

    // 查找Panel下的time Text组件
    private void FindTimeText()
    {
        // 尝试通过名称查找Panel对象
        GameObject panel = GameObject.Find("Panel");
        if (panel != null)
        {
            // 在Panel对象下查找名称为time的Text组件
            timeText = panel.GetComponentInChildren<Text>(true); // true表示查找非激活状态的子对象
            
            // 如果未找到，尝试直接按名称查找
            if (timeText == null)
            {
                Text[] texts = panel.GetComponentsInChildren<Text>(true);
                foreach (Text text in texts)
                {
                    if (text.gameObject.name == "time")
                    {
                        timeText = text;
                        break;
                    }
                }
            }
            
            if (timeText != null)
            {
                // 设置倒计时文本为红色
                timeText.color = Color.red;
            }
        }
    }

    // 三秒倒计时协程
    private IEnumerator CountdownTimer()
    {
        int countdown = 3;
        
        while (countdown > 0)
        {
            if (timeText != null)
            {
                timeText.text = countdown.ToString();
            }
            
            // 使用WaitForSecondsRealtime确保在时间缩放为0时仍然能正常计时
            yield return new WaitForSecondsRealtime(1f);
            countdown--;
        }
        
        // 允许玩家移动
        canMove = true;
        
        // 恢复游戏时间
        Time.timeScale = originalTimeScale;
        
        // 倒计时结束，隐藏文本
        if (timeText != null)
        {
            timeText.gameObject.SetActive(false);
        }
    }

    // Update is called once per frame
    void Update()
    {
        // 确保animator不为null
        if (animator != null)
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                animator.SetBool("jump", true);
            }

            if (Input.GetKeyUp(KeyCode.Space))
            {
                animator.SetBool("jump", false);
            }
        }

        // 确保player不为null
        if (player != null)
        {
            // 只有在倒计时结束后才允许玩家移动
            if (canMove)
            {
                // 获取Rigidbody组件（只获取一次）
                Rigidbody playerRb = player.GetComponent<Rigidbody>();
                
                // 处理玩家移动的通用方法
                HandlePlayerMovement(playerRb);
                
                // 处理键盘输入
                HandleKeyboardInput(playerRb);
                
                // 处理鼠标输入
                HandleMouseInput(playerRb);
            }
            else
            {
                // 倒计时期间，只更新鼠标位置，不处理移动
                lastMouseX = Input.mousePosition.x;
            }
            
            // 检测玩家X坐标是否超出边界
            CheckBoundary(player);
        }
    }

    private void HandlePlayerMovement(Rigidbody playerRb)
    {
        Vector3 newPosition = player.transform.position;
        
        // 玩家自动向前移动
        newPosition.z += forwardSpeed * Time.deltaTime;
        
        if (playerRb != null)
        {
            // 使用MovePosition而不是直接修改transform.position
            playerRb.MovePosition(newPosition);
            transform.position = newPosition; // 同时更新控制对象的位置
        }
        else
        {
            // 如果没有Rigidbody，回退到直接修改位置的方式
            player.transform.position = newPosition;
            transform.position = newPosition;
        }
        
        // 更新PlayerM Text组件显示的距离
        UpdatePlayerMDistance(newPosition.z);
    }
    
    private void HandleKeyboardInput(Rigidbody playerRb)
    {
        // A键向左移动
        if (Input.GetKeyDown(KeyCode.A))
        {
            MovePlayerHorizontally(playerRb, -3f);
        }
        
        // D键向右移动
        if (Input.GetKeyDown(KeyCode.D))
        {
            MovePlayerHorizontally(playerRb, 3f);
        }
    }
    
    private void HandleMouseInput(Rigidbody playerRb)
    {
        // 获取当前鼠标X位置
        float currentMouseX = Input.mousePosition.x;
        
        // 检测鼠标按下
        if (Input.GetMouseButtonDown(0)) // 0表示左键
        {
            isMouseDown = true;
            mouseDownX = currentMouseX;
            mouseDowny = Input.mousePosition.y; // 记录鼠标按下时的Y位置
        }
        
        // 检测鼠标释放
        if (Input.GetMouseButtonUp(0))
        {
            HandleMouseRelease(playerRb, currentMouseX);
        }
        
        // 持续更新上一帧鼠标位置
        lastMouseX = currentMouseX;
    }
    
    private void HandleMouseRelease(Rigidbody playerRb, float currentMouseX)
    {
        // 计算滑动距离
        float swipeDistanceX = currentMouseX - mouseDownX;
        float swipeDistanceY = Input.mousePosition.y - mouseDowny;
        
        // 如果在鼠标按下并释放的过程中向左滑动超过阈值
        if (swipeDistanceX < -swipeThreshold)
        {
            MovePlayerHorizontally(playerRb, -3f);
        }
        
        // 如果在鼠标按下并释放的过程中向右滑动超过阈值
        if (swipeDistanceX > swipeThreshold)
        {
            MovePlayerHorizontally(playerRb, 3f);
        }
        
        // 如果向上滑动超过阈值，则触发跳跃
        if (swipeDistanceY > swipeThreshold && animator != null)
        {
            animator.SetBool("jump", true);
            StartCoroutine(ResetJumpAnimation());
        }
        
        isMouseDown = false;
    }
    
    private void MovePlayerHorizontally(Rigidbody playerRb, float distance)
    {
        if (playerRb != null)
        {
            Vector3 movePosition = player.transform.position;
            movePosition.x += distance;
            playerRb.MovePosition(movePosition);
            transform.position = movePosition;
        }
        else
        {
            player.transform.position = new Vector3(transform.position.x + distance, transform.position.y, transform.position.z);
        }
    }
    
    private void CheckBoundary(GameObject player)
    {
        Vector3 currentPosition = player.transform.position;
        
        // 检测玩家X坐标是否超出边界(-6或6)
        if (Mathf.Abs(currentPosition.x) >= 6f)
        {
            // 根据当前超出的方向，将玩家位置弹回-3或3
            if (currentPosition.x >= 6f)
            {
                currentPosition.x = 3f; // 右侧边界，弹回3
            }
            else
            {
                currentPosition.x = -3f; // 左侧边界，弹回-3
            }
            
            // 更新玩家位置
            player.transform.position = currentPosition;
            transform.position = currentPosition;
            
            // 如果有Rigidbody组件，也更新其位置
            Rigidbody playerRb = player.GetComponent<Rigidbody>();
            if (playerRb != null)
            {
                playerRb.MovePosition(currentPosition);
            }
            
            // 弹回游戏区域后播放死亡动画
            PlayerDeath();
        }
    }

    public void LateUpdate()
    {
        // 确保Camera.main不为null，并且存在子对象
        if (Camera.main != null && transform.childCount > 0)
        {
            Camera.main.transform.position = Vector3.Lerp(
                Camera.main.transform.position, 
                transform.GetChild(0).position, 
                Time.deltaTime * 30
            );
        }
    }

    // 协程函数，用于在短暂延迟后重置jump动画状态
    private IEnumerator ResetJumpAnimation()
    {
        yield return new WaitForSeconds(0.1f);
        if (animator != null)
        {
            animator.SetBool("jump", false);
        }
    }
    
    
    // 更新PlayerM Text组件显示的距离
    private void UpdatePlayerMDistance(float distance)
    {
        if (playerMText != null)
        {
            // 格式化距离，保留1位小数
            playerMText.text = distance.ToString("F2");
        }
        else
        {
            // 如果playerMText为null，尝试重新查找
            FindPlayerMText();
            if (playerMText != null)
            {
                playerMText.text = distance.ToString("F2");
            }
        }
        
        // 移除对NewText的更新，只在PlayerM Text组件中显示玩家移动距离
        // 玩家移动距离只显示在playerM text组件下
    }

    // 检测玩家与建筑物的碰撞
    private void OnCollisionEnter(Collision collision)
    {
        // 检查碰撞对象的标签
        if (collision.gameObject.CompareTag("Obstacle") || collision.gameObject.CompareTag("Building"))
        {
            // 调用PlayerDeath方法
            PlayerDeath();
        }
    }
    
    /// <summary>
    /// 处理与触发器（如金币）的碰撞
    /// </summary>
    private void OnTriggerEnter(Collider other)
    {
        // 记录碰撞信息
        Debug.Log("Player检测到与触发器的碰撞: " + other.gameObject.name + ", 标签: " + other.gameObject.tag);
        
        // 检查碰撞对象是否为金币
        if (other.CompareTag("Coin"))
        {
            Debug.Log("Player直接检测到与金币的碰撞: " + other.gameObject.name);
            
            // 作为最后的备用方案，确保金币一定会消失
            // 检查金币是否已经被标记为销毁（通过比较名称是否包含"Destroyed"）
            if (!other.gameObject.name.Contains("Destroyed"))
            {
                Debug.Log("Player触发金币备用销毁逻辑");
                
                // 重命名金币以避免重复销毁
                other.gameObject.name = "Destroyed_Coin_" + System.Guid.NewGuid().ToString().Substring(0, 8);
                
                // 立即禁用渲染器提供视觉反馈
                MeshRenderer renderer = other.GetComponent<MeshRenderer>();
                if (renderer != null)
                {
                    renderer.enabled = false;
                    Debug.Log("Player备用逻辑: 已禁用金币渲染器");
                }
                
                // 禁用碰撞器防止重复收集
                Collider collider = other.GetComponent<Collider>();
                if (collider != null)
                {
                    collider.enabled = false;
                    Debug.Log("Player备用逻辑: 已禁用金币碰撞器");
                }
                
                // 延迟销毁金币，给其他系统时间处理
                Debug.Log("Player备用逻辑: 准备销毁金币对象");
                Destroy(other.gameObject, 0.1f);
                Debug.Log("Player备用逻辑: 金币销毁命令已发送");
            }
            else
            {
                Debug.Log("Player检测到已标记为销毁的金币，跳过备用销毁逻辑");
            }
        }
    }

    // 玩家死亡逻辑
    private void PlayerDeath()
    {
        // 获取玩家当前位置，用于显示距离
        float currentDistance = 0;
        if (player != null)
        {
            currentDistance = player.transform.position.z;
        }
        
        // 停止玩家移动
        forwardSpeed = 0;
        
        
        // 可以添加死亡动画
        if (animator != null)
        {
            animator.SetTrigger("Die");
            
            // 添加一个备用方案，直接设置动画状态
            // 检查是否有"Die"状态
            if (animator.HasState(0, Animator.StringToHash("Die")))
            {
                animator.Play("Die", 0, 0f);
            }
            else if (animator.HasState(0, Animator.StringToHash("die")))
            {
                animator.Play("die", 0, 0f);
            }
        }
        else
        {
            // 如果animator为null，尝试重新获取
            if (player != null)
            {
                animator = player.GetComponent<Animator>();
                
                if (animator != null)
                {
                    animator.SetTrigger("Die");
                }
            }
        }
        
        // 游戏暂停
        Time.timeScale = 0;
        
        // 查找并显示结束面板
        GameObject panel = GameObject.Find("GameOver");
        if (panel != null)
        {
            // 确保面板可见
            panel.SetActive(true);
            
            // 更新PlayerM Text组件显示的最终距离
            if (playerMText != null)
            {
                playerMText.text = currentDistance.ToString("F2");
            }
            else
            {
                // 如果playerMText为null，尝试重新查找
                FindPlayerMText();
                if (playerMText != null)
                {
                    playerMText.text = currentDistance.ToString("F2");
                }
            }
        }
        
        // 开启协程，等待动画播放完成后再禁用玩家控制
        StartCoroutine(DisablePlayerControlAfterAnimation());
    }
    
    // 协程函数，等待动画播放完成后禁用玩家控制
    private IEnumerator DisablePlayerControlAfterAnimation()
    {
        // 恢复时间以允许动画播放
        Time.timeScale = 1f;
        
        // 等待2秒以确保死亡动画播放完成
        // 注意：这个时间应该根据实际死亡动画的长度进行调整
        yield return new WaitForSeconds(1f);
        
        // 再次暂停游戏
        Time.timeScale = 0;
        
        // 禁用玩家控制
        enabled = false;
    }
    
    // 通用的动画事件处理函数，用于捕获未指定函数名称的动画事件
    public void AnimationEventCallback()
    {
        // 这个函数可以捕获任意未指定具体函数名称的动画事件
        // 防止Unity控制台显示错误信息
        Debug.Log("捕获到动画事件调用，但未指定具体函数名称");
    }
    
    // 查找Panel下的NewText组件
    private void FindNewText()
    {
        // 尝试通过名称查找Panel对象
        GameObject panel = GameObject.Find("Panel");
        if (panel != null)
        {
            // 直接按名称查找NewText组件
            GameObject newTextObj = panel.transform.Find("NewText")?.gameObject;
            
            if (newTextObj != null)
            {
                newText = newTextObj.GetComponent<Text>();
                if (newText != null)
                {
                    Debug.Log("成功找到了NewText组件");
                    // 初始化NewText显示
                    newText.text = "0.00";
                    return;
                }
            }
            
            // 如果通过transform.Find未找到，尝试通过GetComponentsInChildren遍历查找
            Text[] texts = panel.GetComponentsInChildren<Text>(true);
            foreach (Text text in texts)
            {
                if (text.gameObject.name == "NewText")
                {
                    newText = text;
                    Debug.Log("通过遍历找到NewText组件");
                    // 初始化NewText显示
                    newText.text = "0.00";
                    return;
                }
            }
            
            // 如果仍然未找到，尝试直接查找场景中名为NewText的GameObject
            GameObject sceneNewTextObj = GameObject.Find("NewText");
            if (sceneNewTextObj != null)
            {
                newText = sceneNewTextObj.GetComponent<Text>();
                if (newText != null)
                {
                    Debug.Log("在场景中直接找到了NewText组件");
                    // 初始化NewText显示
                    newText.text = "0.00";
                    return;
                }
            }
            
            Debug.LogWarning("在Panel对象下未找到NewText组件");
        }
        else
        {
            Debug.LogWarning("未找到Panel对象，尝试直接查找NewText");
            // 未找到Panel，直接查找场景中名为NewText的GameObject
            GameObject sceneNewTextObj = GameObject.Find("NewText");
            if (sceneNewTextObj != null)
            {
                newText = sceneNewTextObj.GetComponent<Text>();
                if (newText != null)
                {
                    Debug.Log("在场景中直接找到了NewText组件");
                    // 初始化NewText显示
                    newText.text = "0.00";
                }
            }
            else
            {
                Debug.LogWarning("也未在场景中找到NewText组件");
            }
        }
    }
}
